package com.tongtong.controller;

import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.tongtong.common.WebConstants;
import com.tongtong.controller.entity.req.LoginReq;
import com.tongtong.controller.entity.vo.LoginVO;
import com.tongtong.controller.user.entity.User;
import com.tongtong.controller.user.service.UserService;
import com.tongtong.utils.ChannelUtilsV2;
import com.tongtong.utils.RedisUtils;
import com.tt.hotkey.idgen.YitIdHelper;
import com.tt.utils.ChineseNameGenerator;
import com.tt.utils.R;
import com.tt.utils.TripleCheckDigitUtil;
import jodd.io.NetUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * @Title: LoginController
 * @Author zl
 * @Package com.ttio.web
 * @Date 2025/2/5 11:48
 * @description: 登录controller
 */
@Slf4j
@RestController
@RequestMapping("/")
public class ApiController {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserService userService;

    /**
     * 生成用户唯一编码及名称
     * @return
     */
    @GetMapping("/index")
    public R getIndex(HttpServletRequest request){
        String clientIP = ServletUtil.getClientIP(request, null);
        long key = YitIdHelper.nextId();
        Map<String,Object> maps = new HashMap<>();
        String account = TripleCheckDigitUtil.addCheckDigits(String.valueOf(key));
        String chineseName = ChineseNameGenerator.generateChineseName();
        User user = new User();
        user.setAccount(account);
        user.setIp(clientIP);
        user.setUserName(chineseName);
        userService.save(user);
        maps.put("userName",chineseName);
        maps.put("userId",account);
        return R.ok().put("data",maps);
    }

    /**
     * 获取房间列表及在线人数
     */
    @GetMapping("/queryRoom")
    public R queryRoom(){
        List<LoginVO.RoomInfo> roomInfos = new LinkedList<>();
        LoginVO.RoomInfo baseRoom = new LoginVO.RoomInfo("1", "公共聊天室", 0);
        baseRoom.setUserCount(RedisUtils.setMembers(WebConstants.redisRoomUserKey + baseRoom.getRoomId()).size());
        roomInfos.add(baseRoom);
        List<Object> objects = RedisUtils.getWithExpires(WebConstants.redisRoomKey);
        objects.stream().forEach(item -> {
            LoginVO.RoomInfo roomInfo = JSONUtil.toBean(item.toString(), LoginVO.RoomInfo.class);
            roomInfo.setUserCount(RedisUtils.setMembers(WebConstants.redisRoomUserKey + roomInfo.getRoomId()).size());
            roomInfos.add(roomInfo);
        });
        return R.ok().put("data",roomInfos);
    }
    /**
     * 创建房间信息
     */
    @PostMapping("/createRoom")
    public R createRoom(@RequestBody LoginReq.createRoom createRoom){
        try{
            long key = YitIdHelper.nextId();
            String roomId = TripleCheckDigitUtil.addCheckDigits(String.valueOf(key));
            createRoom.setRoomId(roomId);
            //存储房间用户列表
            RedisUtils.putWithExpire(WebConstants.redisRoomKey,roomId,JSONUtil.toJsonStr(createRoom),30,TimeUnit.MINUTES);
            return R.ok();
        }catch (Exception e ){
            e.printStackTrace();
        }
        return R.error("创建房间失败");
    }
    /**
     * 获取房间用户列表
     */
    @GetMapping("/queryRoomUser")
    public R queryRoomUser(String roomId){
        List<LoginVO.UserInfo> userList = new LinkedList<>();
        String redisKey = WebConstants.redisRoomUserKey + roomId;
        RedisUtils.setMembers(redisKey).forEach(item -> {
            LoginVO.UserInfo user = new LoginVO.UserInfo();
            String[] split = item.split("=");
            String userId = split[0];
            String userName = split[1];
            user.setUserId(userId);
            user.setUserName(userName);
            userList.add(user);
        });
        return R.ok().put("data",userList);
    }

    /**
     * 用户加入房间
     * @return
     */
    @PostMapping("/joinRoom")
    public R joinRoom(@RequestBody LoginReq.user2Room user2Room){
        RLock lock = redissonClient.getLock(user2Room.getUserId());
        try{
            lock.lock(5, TimeUnit.SECONDS);
            ChannelUtilsV2.joinRoomUser(user2Room.getUserId(),user2Room.getRoomId());
            return R.ok();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(lock.isHeldByCurrentThread() && lock.isLocked()){
                lock.unlock();
            }
        }
        return R.error();
    }

    /**
     * 离开房间
     * @return
     */
    @PostMapping("/leaveRoom")
    public R leaveRoom(@RequestBody LoginReq.user2Room user2Room){
        ChannelUtilsV2.UserInfo userInfo = ChannelUtilsV2.queryUserInfoByUserId(user2Room.getUserId());
        RLock lock = redissonClient.getLock(user2Room.getUserId());
        try{
            lock.lock(5, TimeUnit.SECONDS);
            ChannelUtilsV2.leaveRoomUser(userInfo);
            return R.ok();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(lock.isHeldByCurrentThread() && lock.isLocked()){
                lock.unlock();
            }
        }
        return R.error();
    }


}
